use std::{rc::Rc, cell::RefCell};

use crate::{instructions::base::Instruction, rtda::Frame};


// Shift left int
#[derive(Debug, Default)]
pub struct ISHL {}

impl Instruction for ISHL {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        let stack = frame.borrow().get_operand_stack();
        let v2 = stack.borrow_mut().pop_int();
        let v1 = stack.borrow_mut().pop_int();
        let s = v2 & 0x1f; // 取前五个比特，最高31
        let result = v1 << s;
        stack.borrow_mut().push_int(result);
    }
}

// Arithmetic shift right int
#[derive(Debug, Default)]
pub struct ISHR {}

impl Instruction for ISHR {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        let stack = frame.borrow().get_operand_stack();
        let v2 = stack.borrow_mut().pop_int();
        let v1 = stack.borrow_mut().pop_int();
        let s = v2 & 0x1f; // 取前五个比特，最高31
        let result = v1 >> s;
        stack.borrow_mut().push_int(result);
    }
}

// Logical shift right int
#[derive(Debug, Default)]
pub struct IUSHR {}

impl Instruction for IUSHR {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        let stack = frame.borrow().get_operand_stack();
        let v2 = stack.borrow_mut().pop_int();
        let v1 = stack.borrow_mut().pop_int();
        let s = v2 & 0x1f; // 取前五个比特，最高31
        let result = v1 as usize >> s;
        stack.borrow_mut().push_int(result as i32);
    }
}

// Shift left long
#[derive(Debug, Default)]
pub struct LSHL {}

impl Instruction for LSHL {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        let stack = frame.borrow().get_operand_stack();
        let v2 = stack.borrow_mut().pop_int();
        let v1 = stack.borrow_mut().pop_long();
        let s = v2 & 0x3f; // 取前六个比特，最高61
        let result = v1 << s;
        stack.borrow_mut().push_long(result);
    }
}

// Arithmetic shift right long
#[derive(Debug, Default)]
pub struct LSHR {}

impl Instruction for LSHR {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        let stack = frame.borrow().get_operand_stack();
        let v2 = stack.borrow_mut().pop_int();
        let v1 = stack.borrow_mut().pop_long();
        let s = v2 & 0x3f; // 取前六个比特，最高61
        let result = v1 >> s;
        stack.borrow_mut().push_long(result);
    }
}

// Logical shift right long
#[derive(Debug, Default)]
pub struct LUSHR {}

impl Instruction for LUSHR {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        let stack = frame.borrow().get_operand_stack();
        let v2 = stack.borrow_mut().pop_int();
        let v1 = stack.borrow_mut().pop_long();
        let s = v2 & 0x3f; // 取前六个比特，最高61
        let result = v1 as usize >> s;
        stack.borrow_mut().push_long(result as i64);
    }
}
